package com.hxs.learn.service.core;

import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import javax.annotation.Resource;

import com.hxs.learn.constants.core.sql.SqlColConts;
import org.apache.commons.lang3.StringUtils;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;

import com.hxs.learn.common.entity.BillSequenceKey;
import com.hxs.learn.entity.core.Bill;
import com.hxs.learn.entity.core.BillSequence;
import com.hxs.learn.mapper.core.BillMapper;
import com.hxs.learn.mapper.core.BillSequenceMapper;

/**
 * @author HuXinsheng
 */
@Service
public class BillService {
    private static ReadWriteLock lock = new ReentrantReadWriteLock();
    private static final String PAD_STR = "0";
    @Resource
    private BillMapper billMapper;
    @Resource
    private BillSequenceMapper billSequenceMapper;

    @Transactional(rollbackFor = Exception.class)
    public String newBillNo(BillSequenceKey key) {

        // 加锁
        lock.writeLock().lock();

        try {
            Bill b = new Bill();

            b.setCode(key.getCode());

            Bill bill = billMapper.selectOne(b);
            int seqVal = 1;
            BillSequence po = new BillSequence();

            po.setCode(key.getCode());

            BillSequence sequence = billSequenceMapper.selectOne(po);

            if (sequence == null) {
                sequence = new BillSequence();
                sequence.setCode(key.getCode());
                sequence.setSequence(seqVal);
                billSequenceMapper.insert(sequence);
            } else {
                seqVal = sequence.getSequence() + 1;
                sequence.setSequence(seqVal);

                Wrapper<BillSequence> wrapper = new EntityWrapper<>();

                wrapper.eq(SqlColConts.CODE, sequence.getCode());
                billSequenceMapper.update(sequence, wrapper);
            }

            int num = bill.getNum();
            String prefix = bill.getPrefix();
            String dateFormat = bill.getDateFormat();

            if (dateFormat == null) {
                dateFormat = "";
            }

            if (prefix == null) {
                prefix = "";
            }
            if (num > 0) {
                return prefix + new SimpleDateFormat(dateFormat).format(new Date())
                        + StringUtils.leftPad(String.valueOf(seqVal),
                        num,
                        PAD_STR);
            } else {
                return prefix + new SimpleDateFormat(dateFormat).format(new Date());
            }
        } finally {

            // 解锁
            lock.writeLock().unlock();
        }
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
